package com.flute.icrawler.framework.executor;

import java.util.Hashtable;
import java.util.Iterator;

import com.flute.icrawler.app.processor.AbstractProcessor;
import com.flute.icrawler.framework.autoadjust.IAdjustable;
import com.flute.icrawler.framework.framework.LocalCrawlUrlPool;

/**
 * 让processor进行多线程处理 实现IAdjustable接口，使得线程数可以自我调整
 * 
 * @author Administrator
 * 
 */

public class ProcessorExecutor implements IAdjustable {
	private int threadCount;
	private Hashtable<Long, MultiThreadProcessor> threadList;
	private LocalCrawlUrlPool pool;
	private AbstractProcessor processor;
	private int maxCount;
	private int minCount;

	public ProcessorExecutor(AbstractProcessor processor, LocalCrawlUrlPool pool) {
		this.processor = processor;
		this.pool = pool;
		this.threadList = new Hashtable<Long, MultiThreadProcessor>();
		this.threadCount = 2;
		this.maxCount = 50;
		this.minCount = 1;
	}

	public void execute() {
		for (int i = 0; i < threadCount; i++) {
			MultiThreadProcessor thread = new MultiThreadProcessor(processor,
					pool, this);
			threadList.put(thread.getId(), thread);
			thread.start();
		}
	}

	public synchronized void increase() {
		if (threadList.size() < maxCount) {
			MultiThreadProcessor thread = new MultiThreadProcessor(processor,
					pool, this);
			threadList.put(thread.getId(), thread);
			thread.start();
		}
	}

	public synchronized void decrease() {
		if (threadList.size() > 1 && threadList.size() > minCount) {
			Iterator<Long> iterator = threadList.keySet().iterator();
			while (iterator.hasNext()) {
				long threadId = iterator.next();
				if (threadList.get(threadId) != null) {
					threadList.get(threadId).setFinish(true);
					threadList.remove(threadId);
					break;
				}
			}
		}
	}

	public int getCount() {
		return threadList.size();
	}

	public int getAliveCount() {
		int count = 0;
		synchronized (threadList) {
			for (long threadId : threadList.keySet()) {
				if (threadList.get(threadId).isAlive()) {
					count++;
				}
			}
		}

		return count;
	}

	public void removeDeadThread(long threadId) {
		threadList.remove(threadId);
	}

	public void setThreadCount(int threadCount) {
		this.threadCount = threadCount;
	}

	public int getMaxCount() {
		return maxCount;
	}

	public void setMaxCount(int maxCount) {
		this.maxCount = maxCount;
	}

	public int getMinCount() {
		return minCount;
	}

	public void setMinCount(int minCount) {
		this.minCount = minCount;
	}
}